package ranking

import (
	"context"
	"strings"

	"gitee.com/wchpub/fnsvr"
	"gitee.com/wchpub/xeSvrPub/blocks/mainBlock"
	"github.com/redis/go-redis/v9"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"go.mongodb.org/mongo-driver/mongo"
)

type RankingUserInfo struct {
	Name    string `bson:"name,omitempty" json:"name,omitempty"`
	OpenId  string `bson:"openid,omitempty" json:"openid,omitempty"`
	SkinId  int    `bson:"skinId,omitempty" json:"skinId,omitempty"`
	SkinIdx int    `bson:"skinIdx,omitempty" json:"skinIdx,omitempty"`
	Face    bool   `bson:"face,omitempty" json:"face,omitempty"` //是否上传了头像
}

// 排行榜上的用户信息
type MongoRankingUserInfo struct {
	ID primitive.ObjectID `bson:"_id"` // 强制映射为ObjectId类型
	RankingUserInfo
}

// mongo排行榜上的集合名
func RankingMongoCollectionName(gameDb *fnsvr.Mogo, iosCode string) string {
	var lowerIosCode string
	if iosCode == "" {
		lowerIosCode = ""
	} else {
		lowerIosCode = strings.ToLower(iosCode)
	}

	return "ranking_" + lowerIosCode
}

// 添加用户到排行榜
func RankingAdd(gameDb *fnsvr.Mogo, openid string, mainBk *mainBlock.Data) error {
	/*
		mainBk.PreLoad(
			mainBlock.Key_RankingTeam,
			mainBlock.Key_Nickname,
			mainBlock.Key_ChooseSkinId,
			mainBlock.Key_ChooseSkinIdx,
			mainBlock.Key_Face,
		)

		iosCode, err := mainBk.RankingTeam()
		if err != nil {
			return err
		}

		face, err := mainBk.Face()
		if err != nil {
			return err
		}

		name, err := mainBk.Nickname()
		if err != nil {
			return err
		}

		skinId, err := mainBk.ChooseSkinId()
		if err != nil {
			return err
		}
		skinIdx, err := mainBk.ChooseSkinIdx()
		if err != nil {
			return err
		}

		dbid, err := fnsvr.GenerateMongoDbId(openid)
		if err != nil {
			return err
		}

		doc := &MongoRankingUserInfo{
			ID: dbid,
			RankingUserInfo: RankingUserInfo{
				Name:    name,
				OpenId:  openid,
				SkinId:  skinId,
				SkinIdx: skinIdx,
				Face:    face,
			},
		}

		collectionName := RankingMongoCollectionName(gameDb, iosCode)
		_, err = gameDb.InsertOne(collectionName, doc)
		if err == fnsvr.ErrMongoDeadlineExceeded {
			return fnsvr.ErrMongoDeadlineExceeded
		}
	*/
	return nil
}

// 清空mongodb排行集合，redis中的数据仍会保留
func ClearMongoRanking(gameDb *fnsvr.Mogo, iosCode string) error {
	collectionName := RankingMongoCollectionName(gameDb, iosCode)
	collection := gameDb.GetCollection(collectionName)

	// 清空集合
	_, err := collection.DeleteMany(context.Background(), bson.M{})
	if err != nil {
		return err
	}

	return nil
}

const (
	MaxLoadCityRankingPlayerCount = 31 //每个城市装载的玩家数据上限
)

// 缓存用户排行榜到redis
func GetCityRankingPlayerList(gameDb *fnsvr.Mogo, redisConn *redis.Client, iosCode string) ([]*RankingUserInfo, error) {
	//展示30个，缓存31个，客户端判断从榜上排除自己

	// 构建聚合管道
	pipeline := mongo.Pipeline{
		{{
			Key: "$sample",
			Value: bson.D{{
				Key:   "size",
				Value: MaxLoadCityRankingPlayerCount,
			}},
		}},
	}

	collectionName := RankingMongoCollectionName(gameDb, iosCode)
	collection := gameDb.GetCollection(collectionName)
	cursor, err := collection.Aggregate(context.TODO(), pipeline)
	if err != nil {
		return nil, err
	}
	defer cursor.Close(context.TODO())

	// 处理结果
	var results []*MongoRankingUserInfo
	if err = cursor.All(context.TODO(), &results); err != nil {
		return nil, err
	}

	list := []*RankingUserInfo{}
	for _, info := range results {
		list = append(list, &info.RankingUserInfo)
	}

	return list, nil
	/*
		listStr, err := json.Marshal(list)
		if err != nil {
			return err
		}
		redisKey := "ranking:iso:" + iosCode

		ctx := context.Background()
		err = redisConn.Set(ctx, redisKey, listStr, time.Hour*24).Err()
		if err != nil {
			return err
		}

		return nil*/
}
